﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Core.Interface;
using ThreadTask = System.Threading.Tasks;

namespace PServiceBus.Core.Runtime.Extensions {
    public static class MessageHandlerExtension {
        public static void Handle<TMessage>(this IMessageHandler<TMessage> handler, IList<TMessage> messages, string rawMessage) where TMessage : class {
            if (messages.Count < 1) return;
            if (handler.HandleInListenerThread) HandleSync(handler, messages, rawMessage);
            else HandleAsync(handler, messages, rawMessage);
        }

        public static void HandleAsync<TMessage>(this IMessageHandler<TMessage> handler, IList<TMessage> messages, string rawMessage) where TMessage : class {
            ThreadTask.Task.Factory.StartNew(o =>
            {
                var tuple = o as Tuple<IMessageHandler<TMessage>, IList<TMessage>, string>;
                HandleSync(tuple.Item1, tuple.Item2, tuple.Item3);
            }, new Tuple<IMessageHandler<TMessage>, IList<TMessage>, string>(handler, messages, rawMessage));
        }

        public static void HandleSync<TMessage>(this IMessageHandler<TMessage> handler, IList<TMessage> messages, string rawMessage) where TMessage : class {
            var ex = MethodHelper.Try(() => handler.OnMessageReceived(new MessageReceivedArgs<TMessage>(messages, DateTime.Now)));
            handler.HandleError(ex, messages, rawMessage);
        }

        public static void HandleError<TMessage>(this IMessageHandler<TMessage> handler, Exception ex, IList<TMessage> messages, string rawMessage = null) where TMessage : class {
            if (ex == null) return;
            var handlerErrorArgs = new HandleErrorArgs<TMessage>(ex, messages) { RawMessage = rawMessage };
            handler.OnErrorReceived(handlerErrorArgs);
            if (!handlerErrorArgs.Continue) handler.Stop();
        }
    }
}
